Repository navigation
fix(kaos,kdrv): What the end-of-line station needed, and the NFC reader's SPI off DMA - #127
Open
luismiKode wants to merge 6 commits into
Open
luismiKode wants to merge 6 commits into
luismiKode wants to merge 6 commits into
Conversation
…indow to verify With a tag close to the coil the signal is strong and the half-bit estimate settled on 16 or 17 samples where the true width at RF/64 and 80 kHz is 20.5 (the windows that decoded measured 18 to 20), so no window gave a frame (-2). The host cases model it as an asymmetric envelope. The decoder now tries the measured width first and then trial widths of 14 to 24 samples, scaled with the sampling rate; the parity checks still decide what is a frame. The clone's verify read one window after the write, and the first one is flat while the front end settles, so a good copy ended in "clone not verified". It now reads up to four windows. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UAYt4seiRecKrhvsophR8u
The final station's bench operator (test_dot_final.py --operator-sim) answers the buttons and touch prompts with the console's btn and touch verbs. Both verbs answered ok and neither row ever heard them: the buttons row judges only what the debounce of the pins confirms, and the touch row sums only samples read from the panel, so every step ended in its timeout (20 s and 40 s) and a station with nobody at it could not finish a run. An injected button now reaches the row's judge as a press of the board's own button, and an injected finger is summed and judged at its lift, the way a tap read from the panel is. Outside a running row nothing changes. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UAYt4seiRecKrhvsophR8u
…e final station The card row writes a megabyte and reads it back against its pattern, and then leaves both phases out of its verdict: the verdict is the slot's, so that a counterfeit card that refuses writes does not condemn a good board. At the final station the card is the station's own and a good one, and there a megabyte the card will not take, or does not give back the same, passed the Kode all the same. AO_Autotest already hears the row's phases. For the final station's client a failed write or read-back now fails the row whatever the owner answered; for every other client the owner's verdict stands. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UAYt4seiRecKrhvsophR8u
…nd clock The final station passed the C5's card on any width: a link that had fallen back to one data line, or to a slower clock, because a line did not reach the C5, left the station as a good card. The production c5 row has always asked for the board's width and clock; the station's check now asks for the same. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UAYt4seiRecKrhvsophR8u
The magnetometer row passed on the part's identity and one conversion. The self-test's shift was read and logged as "a reading, not judged", and the record the console already prints for it (step 2, which the signals describe as judged on its magnitude) was never published. An axis that does not move still names itself and still converts, so a part with a dead axis passed. The datasheet gives the procedure and no figure, so the floor is not a spec: 150 mG an axis, where a board that works shows about 1000 (one board measured: 1065, 986, 995). The row now publishes the step, fails when an axis stays under the floor, and fails when the self-test cannot be run at all. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UAYt4seiRecKrhvsophR8u
… what the chip never sent At the end-of-line station the reader now and then stopped seeing its tag for the rest of a boot, with nothing in the log: about one boot in ten. Around it came single windows with no tag, "the reader would not wake from rest", an identity cached as 0x00 at boot, "amplitude conversion did not complete", and once the nfc task spinning in RFAL until the watchdog. They were one fault. The port handed ESP-IDF buffers in PSRAM with SPI_TRANS_DMA_USE_PSRAM, a path that shares the PSRAM's bus, and now and then a read came back holding something the chip never sent: the IO configuration read 0x00, 0x37, 0x67 or 0xF7 where a trace of every write showed nothing had written it and the chip held 0x07. ESP-IDF raised neither SPI_TRANS_DMA_RX_FAIL nor SPI_TRANS_DMA_TX_FAIL for it. RFAL acts on what it reads, so one bad read was a status bit that never came, an oscillator "not stable", or a FIFO with no tag in it. The bus is opened without DMA. The peripheral then takes a transaction from its own 64-byte buffer, filled and emptied by the CPU, and a longer access goes out in pieces. That is safe because the chip-select is a pin this port drives by hand and RFAL holds it across the whole access. The two PSRAM buffers and their allocation go; a piece's buffers are 128 bytes of internal RAM. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UAYt4sNGU1gkMrcPpLheZ3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Six fixes from a night's runs of the end-of-line station (E5) with a DVT in the fixture. All were found there, changed and run again on the same board. Three came out of reading what each row of the station really judges, and the last is a fault in the NFC reader's port that the station only made visible.
fix(kdrv): Decode a close EM4100 tag and give a clone more than one window to verify
With the tag close to the coil the half-bit estimate settled on 16 or 17 samples where the true width at RF/64 and 80 kHz is 20.5, so no window gave a frame. The decoder tries the measured width first and then trial widths of 14 to 24 samples, scaled with the sampling rate; the parity checks still decide what is a frame. The clone's verify reads up to four windows, since the first one is flat while the front end settles.
On the board:
test component=rfidfailed 5 of 5 with the station's disc in the nest before, and passed 10 of 10 in a row after, three times over tonight (the last on this branch, which is develop with #124's LF carrier change). Host cases added intest_krfid_em4100.c.fix(kaos): Let the buttons and touch rows judge what the console injects
The station's bench operator (
test_dot_final.py --operator-sim) answers the buttons and touch prompts withbtnandtouch. Both verbs answered ok and neither row heard them: the buttons row judges what the debounce of the pins confirms, the touch row sums samples read from the panel. Every step ran out its time (20 s and 40 s) and a station with nobody at it could not finish a run.An injected button now reaches the row's judge as a press of the board's own button, and an injected finger is summed and judged at its lift. The injection travels in the event (a
ButtonEvtunderBUTTONS_INJECT_SIG, aTouchEvtunderTOUCH_INJECT_SIG), is posted only while a row is running, and the console names AO_Touch weakly, sominimalstill links without it.One thing to decide rather than discover: with this the buttons and touch rows no longer tell a press injected over the console from a physical one. The station marks a pass run with
--operator-simas BENCH and does not record it, but the firmware accepts the path. If the rows should refuse injections outside a bench session, say so and I will gate it.On the board: 6 of 6 buttons and 2 of 2 touches in each of 10 passes with
--operator-sim, a pass in 26 to 30 s. Four host cases added (test_buttons_ao.c,test_touch_ao.c).fix(kaos): Let the card's write and read-back decide the sd row at the final station
The sd row runs five phases (identify, read4, read1, a megabyte written, the read-back compared) and its verdict uses the first two, on purpose: a card that will not take a write must not condemn a good slot. At the final station the card is the station's own, a good one, and a board whose slot cannot write passed. Only in AO_Autotest and only for the station's client, a failed write or read-back now fails the row.
storage_ao.cis not touched and "a card that refuses to be written to does not condemn the slot" stands everywhere else.On the board: the five phases pass and the row is PASS in every pass. The failing path is proven on the host only (
test_autotest_ao.c): there is no card at the station that refuses a write.fix(kaos): Ask the station's C5 card for the board's own SDIO width and clock
The station's radio card passed with any width above zero, so a link that had fallen back to one data line or a slower clock left as a good card. It asks for
KBSP_C5_SDIO_WIDTHandKBSP_C5_SDIO_KHZ, as the productionc5row always has. Host case added intest_test_dot_ao.c.On the board: "SDIO 4x40000kHz", the row PASS in every pass.
fix(kaos): Fail the mag row on an axis the self-test does not move
The mag row passed on the part's identity and one conversion. The self-test's shift was logged "a reading, not judged" and step 2 (
MAG_TEST_ST, whichkqp_signals.hdescribes as judged and the console already prints) was not published. It is published now, an axis that moves under 150 mG fails the row, and so does a self-test that does not run.The floor is a choice, not a datasheet figure (the datasheet gives the procedure and no number), and the host case said on purpose that it was not judged for want of one. What it stands on: two boards. The station's DVT in its nest, with the magnetic connector's magnet a few millimetres away, shifts 935 to 1082 mG an axis over 25 readings; another DVT loose on a desk shifts 1003 to 1088 over five. If you would rather keep it unjudged until more boards are measured, or judge it only for the station's client as the sd row does, say so.
fix(kdrv): Take the NFC reader's SPI off DMA, where a read could hold what the chip never sent
At the station the reader now and then stopped seeing its tag for the rest of a boot, with nothing in the log: about one boot in ten. Around it came single windows with no tag (2 % of reads), "the reader would not wake from rest", an identity cached as 0x00 at boot, "amplitude conversion did not complete", and once the nfc task spinning in RFAL until the task watchdog reset the board.
They were one fault. The port handed ESP-IDF buffers in PSRAM with
SPI_TRANS_DMA_USE_PSRAM, a path that shares the PSRAM's bus, and now and then a read came back holding something the chip never sent: the IO configuration read 0x00, 0x37, 0x67 or 0xF7 where a trace of every write showed nothing had written it and the chip held 0x07. ESP-IDF raised neitherSPI_TRANS_DMA_RX_FAILnorSPI_TRANS_DMA_TX_FAILfor it. RFAL acts on what it reads, so one bad read was a status bit that never came, an oscillator "not stable", or a FIFO with no tag in it.The bus is opened without DMA: the peripheral takes a transaction from its own 64-byte buffer, filled and emptied by the CPU, and a longer access goes out in pieces. That is safe because the chip-select is a pin the port drives by hand and RFAL holds it across the whole access. The two PSRAM buffers go; a piece's buffers are 128 bytes of internal RAM (internal RAM static: 409 356 of 417 000).
On the same board, the same loop of
nfc_readafter a reset: with DMA, 10 corrupt register reads in 100 reads, reads of up to 3.4 s and a blind episode; without DMA, 900 reads over 12 boots with none lost, none corrupt, 0.93 s at most, and 40 of 40 passes of the station's programme with the NFC write on.The watchdog panic was seen once in about 150 passes and has not come back; that it was this same fault is likely and not proven (the core dump held no data RAM).
Not run with the change, and worth a look before it is trusted: an access of more than 64 bytes, the only case in which a transfer goes out in more than one piece. A Type 2 tag reads 16 bytes and writes 4 at a time, so nothing at the station crosses it; ISO-DEP exchanges,
nfc_keysandnfc_dumpwould, and there is neither a Type 4 tag, a MIFARE Classic card nor an outside reader at the station. Emulation was started and stopped five times and nobody read it from outside.What was run
tests/target: the full build,nowifi,minimal,minimal_noradioandtestdot, each with its RAM and starts check.--operator-simand the NFC and RFID writes on. With this head: 20 of 20 passes with all 29 rows PASS, 180nfc_readover 3 boots with none lost (0.62 s median, 0.93 s at most), 15 of 15test component=mag. Earlier in the night, with the commits up to the C5 card's bus: 3 of 3 passes; and with the first two only: 45 passes in which the faults they fix did not come back, one of them losing its NFC row to annfc_readthat saw no tag (the fault the last commit here removes). Not run in any of them: the four pad rows (charge, delivery, GND, data loop).kodeOS's side (the launcher's icon memory and the station's
--discover) is in kodediy/KodeOS, which takes this branch in itssdkpointer.🤖 Generated with Claude Code
https://claude.ai/code/session_01UAYt4sNGU1gkMrcPpLheZ3